<script setup lang="ts">
import { h, ref, reactive, onMounted, computed } from 'vue'
import { NModal, NCard, NForm, NGrid, NSpace, NFormItem, NFormItemGi, NInput, NSelect, NAutoComplete, NButton, NDataTable, NPagination, NPopconfirm, useNotification } from 'naive-ui'
import type { FormInst } from 'naive-ui'
import http from '@/tools/http'
import { useUserStore } from '@/stores/userStore'

const userStore = useUserStore()
const emit = defineEmits(["update:dictCode"]);

type RowData = {
    dictCode?: string
    dictName?: string
    dictGroup?: string
    remark?: string
}

const dictTableColumns: any = [
    {
        title: "字典编码",
        key: "dictCode",
        width: 200,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "字典名称",
        key: "dictName",
        width: 120,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "字典分组",
        key: "dictGroup",
        width: 100,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "备注",
        key: "remark",
        width: 100,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "操作",
        key: "actions",
        width: 132,
        fixed: 'right',
        render(rowData: RowData, rowIndex: number) {
            return h(
                NSpace, null,
                () => [
                    userStore.hasAuth("dict:edit") ? h(
                        NButton,
                        {
                            size: "small",
                            onclick: () => openEditDict(rowData)
                        },
                        { default: () => "编辑" }
                    ) : null,
                    userStore.hasAuth("dict:delete") ? h(
                        NPopconfirm,
                        {
                            onPositiveClick: (e: MouseEvent) => deleteDict()
                        },
                        {
                            trigger: () => {
                                return h(
                                    NButton,
                                    {
                                        size: "small",
                                        onclick: () => openDeleteDict(rowData)
                                    },
                                    { default: () => "删除" }
                                )
                            },
                            default: () => { return "确认删除该字典？" }
                        }
                    ) : null
                ]
            )
        }
    }
]

const dictData = reactive<any>({
    list: [],
    pageNum: 1,
    pageSize: 10,
    pages: 1,
    total: 0
})

const dictSearchFormValue = reactive({
    pageNum: 1,
    pageSize: 10,
    dictCode: null,
    dictName: null,
    dictGroup: null
})

let dictSearchFormGroupOptions = reactive<any>([])

onMounted(() => {
    pageDict()
    queryDictGroup()
})

const visiable = ref<boolean>(false)
const title = ref<string>("")
const formRef = ref<FormInst | null>(null)
const formData = reactive<RowData>({
    dictCode: "",
    dictName: "",
    dictGroup: "",
    remark: ""
})

const formDictGroupOptions = computed(() => {
    return dictSearchFormGroupOptions.filter((option: any) => {
        return option.label.includes(formData.dictGroup)
    })
})

const formRules = {
    dictCode: {
        required: true,
        message: '请输入字典编码',
        trigger: ['input']
    },
    dictName: {
        required: true,
        message: '请输入字典名称',
        trigger: ['input']
    }
}

function pageNumChange(pageNum: number) {
    dictSearchFormValue.pageNum = pageNum
    pageDict()
}

function pageSizeChange(pageSize: number) {
    dictSearchFormValue.pageSize = pageSize
    pageDict()
}

let currentRow = ref<number>(-1)

function dataTableRowClicked(rowData: RowData, rowIndex: number) {
    return {
        style: 'cursor: pointer;background-color:#123456;',
        onClick: () => {
            if (currentRow.value !== rowIndex) {
                currentRow.value = rowIndex
                emit('update:dictCode', rowData.dictCode)
            }
        }
    }
}

function updateRowClassName(rowData: RowData, rowIndex: number) {
    if (currentRow.value === rowIndex) {
        return "selected"
    }
    return ""
}

function openAddDict() {
    visiable.value = true
    title.value = "添加字典"
    formData.dictCode = ""
    formData.dictName = ""
    formData.dictGroup = ""
    formData.remark = ""
}

function openEditDict(row: any) {
    visiable.value = true
    title.value = "编辑字典"
    formData.dictCode = row.dictCode
    formData.dictName = row.dictName
    formData.dictGroup = row.dictGroup
    formData.remark = row.remark
}

function openDeleteDict(row: any) {
    formData.dictCode = row.dictCode
    formData.dictName = row.dictName
    formData.dictGroup = row.dictGroup
    formData.remark = row.remark
}

function submit() {
    formRef.value?.validate((errors) => {
        if (!errors) {
            if (title.value === "添加字典") {
                addDict()
            } else {
                updateDict()
            }
            visiable.value = false
        }
    })
}

function pageDict() {
    http.post("/dictionary/page", dictSearchFormValue).then(({ data }) => {
        dictData.pageNum = data.data.pageNum
        dictData.pageSize = data.data.pageSize
        dictData.pages = data.data.pages
        dictData.total = data.data.total
        dictData.list.length = 0
        for (let i = 0; i < data.data.list.length; i++) {
            dictData.list.push(data.data.list[i])
        }
    })
}

function queryDictGroup() {
    http.post("/dictionary/group/query-all").then(({ data }) => {
        dictSearchFormGroupOptions.length = 0
        for (let i = 0; i < data.data.length; i++) {
            dictSearchFormGroupOptions.push({
                label: data.data[i], value: data.data[i]
            })
        }
    })
}

const notification = useNotification()

function addDict() {
    http.post("/dictionary/add", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '添加成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageDict()
            queryDictGroup()
        }
    })
}

function updateDict() {
    http.post("/dictionary/update", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '修改成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageDict()
            queryDictGroup()
        }
    })
}

function deleteDict() {
    http.post("/dictionary/delete", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '删除成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageDict()
            queryDictGroup()
        }
    })
}
</script>

<template>
    <div class="search" style="margin-right:6px;height:108px;">
        <n-form :model="dictSearchFormValue" inline label-placement="left">
            <n-grid :cols="24" :x-gap="24">
                <n-form-item-gi :span="12" label="字典编码" path="dictCode">
                    <n-input v-model:value="dictSearchFormValue.dictCode" placeholder="请输入字典编码" clearable />
                </n-form-item-gi>
                <n-form-item-gi :span="12" label="字典名称" path="dictName">
                    <n-input v-model:value="dictSearchFormValue.dictName" placeholder="请输入字典名称" clearable />
                </n-form-item-gi>
                <n-form-item-gi :span="12" label="字典分组" path="dictGroup">
                    <n-select v-model:value="dictSearchFormValue.dictGroup" :options="dictSearchFormGroupOptions"
                        placeholder="请选择字典名称" clearable>
                    </n-select>
                </n-form-item-gi>
                <n-form-item-gi :span="12">
                    <div class="display-flex-end">
                        <n-button attr-type="button" @click="pageDict()">查询</n-button>
                    </div>
                </n-form-item-gi>
            </n-grid>
        </n-form>
    </div>
    <div class="btn-group" style="margin-right:6px;">
        <n-button v-if="userStore.hasAuth('dict:add')" attr-type="button" @click="openAddDict()">新增</n-button>
    </div>
    <div class="data-table" style="top:204px;margin-right:6px;">
        <n-data-table :scroll-x="652" :scrollbar-props="{ trigger: 'none' }" style="height:100%" flex-height
            :row-class-name="updateRowClassName" :row-props="dataTableRowClicked" :columns="dictTableColumns"
            :data="dictData.list" :bordered="false" />
    </div>
    <div class="pagination" style="margin-right:6px;">
        <n-pagination style="float:right" v-model:page="dictData.pageNum" :page-size="dictData.pageSize"
            :item-count="dictData.total" :page-sizes="[5, 10, 30, 50, 100]" :on-update-page="pageNumChange"
            :on-update-page-size="pageSizeChange" show-quick-jumper show-size-picker />
    </div>
    <n-modal v-model:show="visiable">
        <n-card style="width: 400px" :title="title">
            <n-form ref="formRef" :model="formData" :rules="formRules" label-width="78px" label-placement="left"
                require-mark-placement="left">
                <n-form-item label="字典编码" path="dictCode">
                    <n-input v-model:value="formData.dictCode" :disabled="title === '编辑字典'" placeholder="请输入字典编码" />
                </n-form-item>
                <n-form-item label="字典名称" path="dictName">
                    <n-input v-model:value="formData.dictName" placeholder="请输入字典名称" />
                </n-form-item>
                <n-form-item label="字典分组" path="dictGroup">
                    <n-auto-complete v-model:value="formData.dictGroup" :options="formDictGroupOptions"
                        placeholder="请输入字典分组" />
                </n-form-item>
                <n-form-item label="备注" path="remark">
                    <n-input v-model:value="formData.remark" placeholder="请输入备注" />
                </n-form-item>
            </n-form>
            <template #footer>
                <div class="display-flex-end">
                    <n-space>
                        <n-button attr-type="button" @click="visiable = false">取消</n-button>
                        <n-button attr-type="button" @click="submit()">提交</n-button>
                    </n-space>
                </div>
            </template>
        </n-card>
    </n-modal>
</template>

<style scoped>
:deep(.selected td) {
    background-color: var(--n-th-color-hover);
}

.display-flex-end {
    display: flex;
    width: 100%;
    justify-content: flex-end;
}
</style>